package manager

import (
	"github.com/tianjigames/fairy/constants"
	"github.com/tianjigames/fairy/model"
	"github.com/tianjigames/fairy/template"
	"github.com/topfreegames/pitaya"
	"math"
	"strconv"
)

var CalCulateUtil = &calculateUtil{}

/**
计算工具类 
 */
type calculateUtil struct {

}

/**
一级属性转为二级属性的计算方法
@param base 一级属性值
@param factor 一级属性转为二级属性的因子
@param oth_add 二级属性值
 */
func (p *calculateUtil) CalOriValue(base,factor,oth_add int) int {
	return int(float32(factor) / float32(constants.Per) * float32(base)) + oth_add
}

func (p *calculateUtil) IsValidAttrId(attrId int) bool {
	if attrId <= int(constants.AttrStart) || attrId >= int(constants.AttrMaxIndex) {
		return false
	}

	return true
}

/**
计算法宝的战力值
 */
func (p *calculateUtil) CalFabaoCombatPower(player *model.PlayerObject) int {
	if player == nil {
		return 0
	}

	var value float64 = 0
	end := int(constants.AttrMaxIndex + 1)
	for i:= int(constants.AttrStart) + 1;i<end;i++ {
		attrFlag := constants.GetAttrFlagByValue(i)
		if attrFlag == nil {
			continue
		}

		//基本属性值的战力值
		weight := p.getAttrWeight(*attrFlag,player.GetCareerId())
		if weight > 0 {
			value += float64(LoadPlayerInfoManager.GetFabaoRefixAttr(player,attrFlag))*weight
		}
	}

	value += p.calFabaoSkillCombatPower(player)
	return int(math.Ceil(value))
}


/**
法宝技能的战力值
 */
func (p *calculateUtil) calFabaoSkillCombatPower(player *model.PlayerObject) float64 {
	if player == nil || player.MFabao == nil || player.MFabao.SkillList == nil ||
		len(player.MFabao.SkillList) == 0 {
		return 0
	}

	var value float64 = 0
	fabaoSkill := player.MFabao.SkillList
	for i:=0;i< len(fabaoSkill);i++ {
		if fabaoSkill[i] <= 0 {
			continue
		}

		cfg := pitaya.GetTemplateById(template.FabaoSkillKey,strconv.FormatInt(int64(fabaoSkill[i]),10))
		if cfg == nil {
			continue
		}

		skillBaseCfg := pitaya.GetTemplateById(template.SkillBaseKey,strconv.FormatInt(int64(cfg.(*template.FabaoSkill).SkillBaseID),10))
		if skillBaseCfg == nil {
			continue
		}
		value += float64(skillBaseCfg.(*template.SkillBase).CombatPower)
	}
	return value
}

/**
获取法宝对属性值的影响权重
 */
func (p *calculateUtil) getAttrWeight(attrId constants.AttrFlag,careerId int) float64 {
	var v interface{}
	switch attrId {
	case constants.AttrMaxHp:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentHp)
	case constants.AttrMaxMp:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentMp)
	case constants.AttrAttackPhy:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentPatk)
	case constants.AttrAttackMagic:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentMatk)
	case constants.AttrDefencePhy:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentPdef)
	case constants.AttrDefenceMagic:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentMdef)
	case constants.AttrHit:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentHit)
	case constants.AttrMiss:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentDod)
	case constants.AttrCritical:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentCrit)
	case constants.AttrCritResist:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentTen)
	case constants.AttrCritIncreased:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentCritInc)
	case constants.AttrCritReduction:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentCritRedu)
	case constants.AttrThrough:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentSund)
	case constants.AttrPatty:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentParry)
	case constants.AttrCriticalHit:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentCritHit)
	case constants.AttrStrengthDefuse:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentStrDef)
	case constants.AttrDamageIncreased:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentDamInc)
	case constants.AttrDamageReduction:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentDamRedu)
	case constants.AttrExtraHit:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentExtraHit)
	case constants.AttrExtraMiss:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentExtraDod)
	case constants.AttrExtraCrtical:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentExtraCrit)
	case constants.AttrExtraCritResist:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentExtraTen)
	case constants.AttrExtraThrough:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentExtraSund)
	case constants.AttrExtraPatty:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentExtraParry)
	case constants.AttrAttackIce:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentAtkIce)
	case constants.AttrResistIce:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentResIce)
	case constants.AttrReduceResistIce:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentReduResIce)
	case constants.AttrAttackFire:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentAtkFire)
	case constants.AttrResistFire:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentResFire)
	case constants.AttrReduceResistFire:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentReduResFire)
	case constants.AttrAttackThunder:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentAtkThunder)
	case constants.AttrResistThunder:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentResThunder)
	case constants.AttrReduceResistThunder:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentReduResThunder)
	case constants.AttrAttackPoison:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentAtkPoison)
	case constants.AttrResistPoison:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentResPoison)
	case constants.AttrReduceResistPoison:
		v = pitaya.GetTemplateById(template.ConstantKey,constants.ParamKeyBellipotentReduResPoison)
	}

	if v == nil {
		return 0
	}

	cfg := v.(*template.Constant)
	switch careerId {
	case 1:
		return float64(cfg.Constant3)
	case 2:
		return float64(cfg.Constant4)
	case 3:
		return float64(cfg.Constant4)
	case 4:
		return float64(cfg.Constant4)
	}
	return 0
}
